﻿using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;

using TraceView.Shared;

namespace TraceView.Listeners.EntLib31
{
    [ConfigurationElementType(typeof(CustomTraceListenerData))]
    public sealed class Listener : CustomTraceListener
    {
        private readonly string _applicationName;
        private readonly string[] _servers;

        public Listener()
        {
            _applicationName = Assembly.GetEntryAssembly().GetName().Name;
            _servers = new[] { "localhost" };
        }

        public Listener(string initializeData)
        {
            string[] parts = initializeData.Split(';');
            if (parts.Length > 0)
                _applicationName = string.IsNullOrEmpty(parts[0])
                    ? Assembly.GetEntryAssembly().GetName().Name : parts[0];
            if (parts.Length > 1)
            {
                _servers = new string[parts.Length - 1];
                Array.Copy(parts, 1, _servers, 0, _servers.Length);
            } else
                _servers = new[] { "localhost" };
        }

        public override void Write(string message)
        {
            throw new NotImplementedException();
        }

        public override void WriteLine(string message)
        {
            throw new NotImplementedException();
        }

        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id,
            object data)
        {
            var logEntry = data as LogEntry;
            if (logEntry == null)
                return;

            logEntry.ExtendedProperties.Add("Message", logEntry.Message);
            RegisteredTraceHandler registeredTraceHandler = RegisteredTraceHandlers.Instance[typeof(string).ToString()];
            if (registeredTraceHandler == null)
                return;

            TraceData traceData = logEntry.ToTraceData(registeredTraceHandler);
            traceData.ApplicationName = _applicationName;

            Parallel.ForEach(_servers, server => {
                                           ITraceService traceClient = TraceServiceClient.Create(server);
                                           traceClient.Trace(traceData);
                                       });
        }

        private string GetRandomAppName()
        {
            var rng = new Random((int)DateTime.Now.Ticks);
            int index = rng.Next(AppNames.Length);
            return AppNames[index];
        }
        private static readonly string[] AppNames = new[] { "Desktop", "Desktop Server" };
    }
}